package com.icee.myth.manager.channelHandler;

import com.icee.myth.manager.ServerMessageQueue;
import com.icee.myth.common.protobufMessage.ProtobufMessageType;
import com.icee.myth.manager.message.serverMessage.builder.ManagerMessageBuilder;
import com.icee.myth.protobuf.ExternalCommonProtocol.IntValuesProto;
import com.icee.myth.protobuf.ExternalCommonProtocol.VariableValuesProto;
import com.icee.myth.utils.LogConsts;
import com.icee.myth.utils.MLogger;
import com.icee.myth.utils.StackTraceUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.IOException;

/**
 * Manager服务器连集群处理
 *
 * @author liuxianke
 */
public class ManagerToClusterHandler extends ChannelInboundHandlerAdapter {

    private final int serverId;

    public ManagerToClusterHandler(int serverId) {
        this.serverId = serverId;
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // Add cluster channel close message to message queue
        ServerMessageQueue.queue().offer(
                ManagerMessageBuilder.buildClusterCloseMessage(serverId));
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.printf("a game server connected!!\n");
        // Add cluster channel connected message to message queue
        ServerMessageQueue.queue().offer(
                ManagerMessageBuilder.buildClusterConnectMessage(
                        ctx.channel(), serverId));
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            System.out.println("ManagerToClusterHandlerReceivemessage!");
            // add cluster channel received message to message queue
            ByteBuf cb = (ByteBuf) msg;
            short type = cb.readShort();
//			int length = cb.readInt();

            switch (type) {
                case ProtobufMessageType.MANAGER2CLUSTER_HEARTBEAT: {
                    ServerMessageQueue.queue().offer(
                            ManagerMessageBuilder
                                    .buildClusterHeartbeatMessage(serverId));
                    break;
                }
                case ProtobufMessageType.SERVER2MANAGER_BATTLE_WIN_RATE_RESULT: {
                    IntValuesProto intValues = IntValuesProto.getDefaultInstance()
                            .newBuilderForType()
                            .mergeFrom(new ByteBufInputStream(cb)).build();
                    ServerMessageQueue.queue().offer(
                            ManagerMessageBuilder
                                    .buildBattleWinRateResultMessage(intValues));
                    break;
                }
                case ProtobufMessageType.SERVER2MANAGER_CARD_DRAW_RATE_RESULT: {
                    VariableValuesProto variableValuesProto = VariableValuesProto
                            .getDefaultInstance().newBuilderForType()
                            .mergeFrom(new ByteBufInputStream(cb)).build();
                    ServerMessageQueue
                            .queue()
                            .offer(ManagerMessageBuilder
                                    .buildCardDrawRateResultMessage(variableValuesProto));
                    break;
                }
                case ProtobufMessageType.SERVER2MANAGER_UNINIT_OCCUPY_INFO: {
                    IntValuesProto intValues = IntValuesProto.getDefaultInstance()
                            .newBuilderForType()
                            .mergeFrom(new ByteBufInputStream(cb)).build();
                    ServerMessageQueue.queue().offer(
                            ManagerMessageBuilder
                                    .buildUninitOccupyInfoMessage(intValues));
                    break;
                }
                case ProtobufMessageType.SERVER2MANAGER_FIGHTING_OCCUPY_INFO: {
                    IntValuesProto intValues = IntValuesProto.getDefaultInstance()
                            .newBuilderForType()
                            .mergeFrom(new ByteBufInputStream(cb)).build();
                    ServerMessageQueue.queue().offer(
                            ManagerMessageBuilder
                                    .buildFightingOccupyInfoMessage(intValues));
                    break;
                }
                default:
                    System.out.println("unknow case");
                    break;
            }
        } catch (IOException ex) {
            MLogger.getlogger().log(LogConsts.LOGTYPE_NETERR,
                    StackTraceUtil.getStackTrace(ex));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_DEBUG, StackTraceUtil.getStackTrace(cause));
        MLogger.getlogger().log(LogConsts.LOGTYPE_NETERR,
                "Server[" + serverId + "] is not running.");
        // 关闭与Cluster的连接
//        ctx.channel().close();
    }

}
